/***************************************************************************//**
 * @file app_device.h
 * @brief for device attributes，参数数据管理，考虑将更改频次少的、长度大的 字段放入NVM以节省内存
 * @brief 该h文件处于很底层 可被所有其他层次mac network、app层次的函数包含使用
 * @author ze 
 * @date  2022/7/03.
 * @copyright Copyright 
 ******************************************************************************/
#ifndef _DEVICE_H_
#define _DEVICE_H_

#include "stdint.h"
#include "stdbool.h"

//选择频率，注意枚举值不可修改，对应Rail_channel_config数组内的rf配置寄存器数组索引
typedef enum
{
  RF_FREQ_868MHZ = 0, //868.0-869.9MHz
  RF_FREQ_915MHZ,     //903.0-926.9MHz
  RF_FREQ_433MHZ,
  RF_FREQ_915MHZ_RCM, //915-928MHZ
  RF_FREQ_868MHZ_WPC, //865-868MHZ
  RF_FREQ_MAX
}RF_FREQ_EN;

typedef enum
{
  SPVN_TIME_5MIN = 0,//默认5min
  SPVN_TIME_1MIN, //
  SPVN_TIME_30S,//
  SPVN_TIME_MAX, //
}SPVN_TIME_EN;

typedef enum {
  DEVICE_SOURCE_NVM=0,
  DEVICE_SOURCE_RAM,

}DEVICE_SOURCE_TYPE_EN;
typedef enum {
  EN_DEVICE_RET_STATUS_SUCCESS = 0,
  EN_DEVICE_RET_STATUS_FAIL = -1,
  EN_DEVICE_RET_STATUS_FULL = -2,
  EN_DEVICE_RET_STATUS_FOUND = -3, //已存在相同的设备信息

}DEVICE_RET_STATUS_EN;

#define MAC_ADDRESS_LENGTH                8
#define SN_LENGTH                         16
#define PRF_LENGTH                        3
#define SENSOR_VERSION_LENGTH             3
/**
 * note: 设备类型接入能力设置
 *
 */
#define DEVICE_TYPE_IO_CN                  128
#define DEVICE_TYPE_SOUNDER_CN             12
#define DEVICE_TYPE_KEYPAD_CN              8
#define DEVICE_TYPE_FOB_CN                 64

#define UPDATEME_BC_ID_CN                  (12)
#define SWITCH_BC_ID_CN                    (12)

#define HARD_TYPE_SILICON_LAB_256               (0x01)
#define HARD_TYPE_SILICON_LAB_512               (0x02)


typedef enum{
  /*
   *  I/O 设备类型
   *
   */
  EN_DEVICE_TYPE_IO_FIRST = 0x01,
  EN_DEVICE_TYPE_IO_MC = EN_DEVICE_TYPE_IO_FIRST,
  EN_DEVICE_TYPE_IO_PIR = 0x02,
  EN_DEVICE_TYPE_IO_DT = 0x03,

  EN_DEVICE_TYPE_IO_WATER_LEAK = 0x0A,
  EN_DEVICE_TYPE_IO_FIXED_PA=0x0B,
  EN_DEVICE_TYPE_IO_PORT_PA=0x0C,

  EN_DEVICE_TYPE_IO_TEMP_HUMI = 0x7F,
  EN_DEVICE_TYPE_IO_SMART_PLUG = 0x80,
  EN_DEVICE_TYPE_IO_WEAK_RELAY = 0x81,
  EN_DEVICE_TYPE_IO_STRONG_RELAY = 0x82,

  EN_DEVICE_TYPE_IO_LAST = EN_DEVICE_TYPE_IO_STRONG_RELAY,

  /*
   * sounder设备类型
   *
   */
  EN_DEVICE_TYPE_SOUNDER_FIRST = 0xA0,
  EN_DEVICE_TYPE_IN_SOUND = EN_DEVICE_TYPE_SOUNDER_FIRST,
  EN_DEVICE_TYPE_OUT_SOUND = 0xA1,
  EN_DEVICE_TYPE_SOUNDER_LAST = EN_DEVICE_TYPE_OUT_SOUND,


  /*
   * keypad设备类型
   */
  EN_DEVICE_TYPE_KEYPAD_FIRST = 0xA8,
  EN_DEVICE_TYPE_LED_KEYPAD = EN_DEVICE_TYPE_KEYPAD_FIRST,
  EN_DEVICE_TYPE_KEYPAD_LAST = EN_DEVICE_TYPE_LED_KEYPAD,


  /*
   * fob设备类型
   *
   */
  EN_DEVICE_TYPE_FOB_FIRST = 0xB0,
  EN_DEVICE_TYPE_FOB = EN_DEVICE_TYPE_FOB_FIRST,
  EN_DEVICE_TYPE_FOB_LAST = EN_DEVICE_TYPE_FOB,

}DEVICE_TYPE_EN;

typedef enum {
  /*
   * IO RFMID
   */
  RFMID_EN_INDEX_IO_FIRST = 1,
  RFMID_EN_INDEX_IO_LAST = RFMID_EN_INDEX_IO_FIRST+DEVICE_TYPE_IO_CN-1,

  /*
   * SOUNDER RFMID
   */
  RFMID_EN_INDEX_SOUNDER_FIRST = RFMID_EN_INDEX_IO_LAST+1,
  RFMID_EN_INDEX_SOUNDER_LAST = RFMID_EN_INDEX_SOUNDER_FIRST+DEVICE_TYPE_SOUNDER_CN-1,
/*
 * KEYPAD RFMID
 */
  RFMID_EN_INDEX_KEYPAD_FIRST = RFMID_EN_INDEX_SOUNDER_LAST+1,
  RFMID_EN_INDEX_KEYPAD_LAST = RFMID_EN_INDEX_KEYPAD_FIRST+DEVICE_TYPE_KEYPAD_CN-1,
/*
 * FOB RFMID
 */
  RFMID_EN_INDEX_FOB_FIRST = RFMID_EN_INDEX_KEYPAD_LAST+1,
  RFMID_EN_INDEX_FOB_LAST = RFMID_EN_INDEX_FOB_FIRST+DEVICE_TYPE_FOB_CN-1,

}RFMID_EN;



//设备信息存放于RAM 和 NVM(ROM)两个大地方，其中，地址可不连续，存放在不同的结构体数组中。
#if 0 
typedef struct 
{
    /***Hard Info NVM************************/
    uint8_t pbyKeyM[16]; //NVM only,16 bytes KeyM,it may from QR Code, or transfer from SN; will mixed with key A or B,to protect it    
    uint8_t byDeviceType; //see device type enum
    uint8_t byModelType;
    uint8_t byHardType;  
    //uint8_t pbyMacShortID[2]; //MAc短地址在内存
    uint8_t pbyMacID[8]; //NVM only,8 bytes MAC ADD ,EUI ID
    /****learn changed NVM*******************/
    uint8_t pbyRfVer[3]; //va.b.c, c for test version idx used.
    uint8_t pbySensorVer;
    uint8_t pbyKeyA[16]; //NVM only, 16 bytes KeyA, by device itself's true random generator

    uint8_t byLearnState;    
    uint8_t pbyPanId[3];
    uint8_t pSelfNodeId;
    uint8_t pbySelfRollingCode[4]; //it will changed many times
    uint8_t pbySystemID[3];
    uint8_t pbyLocalId[2];
    uint8_t pbyKeyB[16]; //NVM only, 16 bytes KeyB, get from endpoint's wireless packet
    uint8_t pbySystemKey[16];  //NVM only, 16 bytes systemKey,for roman used.

    /************上行相关信息********************/
    //协议状态配置相关
    uint8_t byMsgSeq;// MAC layer only
    uint8_t byMsgRetry;//MAC layer only
    uint8_t byBattVolt;
    uint8_t byRecvEndpRssi;// 上次接收到的对端发出报文的RSSI值
    uint8_t byTemp;
    uint8_t byQrfR1;
    uint8_t byQrfR2;
    //uint8_t byEchoAseq; //同 byAseq

    //sensor状态配置相关
    uint8_t pbyInOutState[2]; //自身 输入/输出开关量状态

    /************下行相关信息********************/
    //协议状态配置相关
    uint8_t byEndpEchoRssi;//回显的 上次对端接收到的自身报文的RSSI值
    uint8_t byQrfH1;
    uint8_t byQrfH2;
    uint8_t bySpvnTime[2]; //*单位1s，其中0表示心跳不变，维持之前或默认配置，0xFFFF表示心跳关闭，默认为150*2=300s；若无mallocedSlot则使用该值调节TDMA

    //sensor状态配置相关
    uint8_t byAseq; //
    uint8_t pbyOption[4];//下行配置信息，如开、关、模式、等级

    /***************HUB 保存信息************************/
    uint8_t byAntIdx; //哪根天线信号强度更好，仅使用1bit，后续可更新

}DEVICE_RFM_ATTRIBUTE_ST;
#endif

#define NODE_MAX_COUNT                          255     //网络总的节点容量
#define KEY_MAX_LENGTH                          16      //key的长度 16bytes

#define ROLLING_CODE_LENGTH                      4
#define DEVICE_TYPE_LENGTH                       1
#define MODEL_TYPE_LENGTH                        1    
#define HARD_TYPE_LENGTH                         1    
#define FTYPE_LENGTH                             1      
#define OPTION_LENGTH                            3
#define LEDCTRL_LENGTH                           (5+1)
#define OPERATECTRL_LENGTH                       (3+1)
#define PANID_LENGTH                             3
#define GETKEYVALUE_LENGTH                       1
#define RF_TX_POWER_LENGTH                       2
#define RF_CTUNE_LENGTH                          4
#define LFXO_CTUNE_LENGTH                        1
#define OPTION_LENGTH                            3

/************设备独有参数*************************/
#define SMART_PLUG_CALIBRATION_LENGTH           3
#define SMART_PLUG_ENERGY_LENGTH                4
#define SMART_PLUG_TIMES_LENGTH                 4
#define ONOFF_STATE_LENGTH                      1
#define CHILD_LOCK_LENGTH                       1

/*********************************************/

#define OTA_REQUEST_VALUE_LENGTH                 19
#define OTA_REQUEST_KEYVALUE_INFO_LENGTH         17
#define OTA_CONFIRM_VALUE_LENGTH                 19
#define OTA_CONFIRM_KEYVALUE_INFO_LENGTH         17
#define OTA_CONSULT_KEYVALUE_LENGTH              9
#define OTA_CONSULT_KEYVALUE_INFO_LENGTH         7

#define OTA_ID_BUF_MAX                           DEVICE_TYPE_IO_CN
#define FILE_SIZE_LENGTH                         4

#define NODE_JOIN_INFO_LENGTH                   (NODE_MAX_COUNT/8+((NODE_MAX_COUNT%8)==0?0:1))
#define NODE_JOIN_PUB_LENGTH                    NODE_JOIN_INFO_LENGTH

#define MAX_OFFLINE_COUNTDOWN                   (90) //每10S减1 90 = 900s = 15min
#define QRFH2_COUNTDOWN                         (60) //每10S减1 60 = 600s = 10min

typedef enum
{

    /***Hard Info NVM************************/
    ENpbyKeyM = 1, //NVM only,16 bytes KeyM,it may from QR Code, or transfer from SN; will mixed with key A or B,to protect it    
    ENbyModelType,
    ENbyHardType,  
    ENbyDeviceType,
    //ENpbyMacShortID[2]; //MAc短地址在内存
    ENpbyMacID, //NVM only,8 bytes MAC ADD ,EUI ID
    /****learn changed NVM*******************/
    ENpbyRfVer, //va.b.c, c for test version idx used.
    ENpbySensorVer,
    ENpbyKeyA, //NVM only, 16 bytes KeyA, by device itself's true random generator

    ENbyLearnState,   
    ENpbyPanId,
    ENpSelfNodeId,
    ENpbySelfRollingCod, //it will changed many times
    ENpbySystemID,
    ENpbyLocalId,
    ENpbyRfmId,
    ENpbyKeyB, //NVM only, 16 bytes KeyB, get from endpoint's wireless packet
    ENpbySystemKey,  //NVM only, 16 bytes systemKey,for roman used.
    ENpbyBroadcastKey, //NVM ,16bytes
    ENpbyNVMKey,       //NVM key
    ENpbyNVMKeyEN,
    ENpbyDefaultKey1,
    ENpbyDefaultKey2,
    ENpbyCodeABKey,    //RFM存储的codeABKey;HUB存储区域在ENpbyCodeABNode1..。N
    ItselfRollingCode,        //4个字节
    EndDeviceRecvRollingCode,//4个字节
    RfTxPower,  //2 字节
    RfCtune,    //4 字节
    lfxoCtune,  //1字节

    /************上行相关信息********************/
    //协议状态配置相关
    ENbyMsgSeq,// MAC layer only
    ENbyMsgRetry,//MAC layer only
    ENbyBattVolt,
    ENbyRecvEndpRssi,// 上次接收到的对端发出报文的RSSI值
    ENbyTemperature,
    ENbyQrfR1,
    ENbyQrfR2,
    //ENbyEchoAseq; //同 byAseq

    //sensor状态配置相关
    ENpbyInOutState, //自身 输入/输出开关量状态

    /************下行相关信息********************/
    //协议状态配置相关
    ENbyEndpEchoRssi,//回显的 上次对端接收到的自身报文的RSSI值
    ENbyQrfH1,
    ENbyQrfH2,
    ENbySpvnTime, //*单位2s，其中0表示心跳不变，维持之前或默认配置，0xFFFF表示心跳关闭，默认为150*2=300s；若无mallocedSlot则使用该值调节TDMA

    ENbySpvnGroup, //获取分配的槽组别
    ENbySpvnIdx,   //获取分配的槽组别内Id
    //sensor状态配置相关
    ENbyAseq, //
    ENpbyOption,//下行配置信息，如开、关、模式、等级

    /**********设备独有属性*************/
    smartPlugCalibration,   //3 字节
    smartPlugEnergy,        //4 字节
    smartPlugTimes,         //4 字节
    onoffState, //1字节
    childLock,   //1字节

    /***************文件传输 保存信息*********************/
    //只存ram
    ENbyTransFileType, //文件传输类型 1字节
    ENbyOtaUpdatemeID, //最多128字节
    ENbyOtaUpdatemeIDNum, //1字节
    ENbyUpdatemeOrder,  //1字节
    //ENbyHandShakeCount,  //1字节
    ENbyOtaRequestFlag, //0xff物模型是否填充到报文的flag 1字节
    ENbyOtaRequestKeyValue, //文件传输请求物模型
    ENbyOtaConfirmFlag, //0xfd物模型是否填充到报文的flag 1字节
    ENbyOtaConfirmKeyValue, //文件传输确认物模型

    ENbyOtaConSultKeyValue, //文件传输接受物模型 9字节 每次所有节点的value值一样，所以没有按节点保存
    ENbyReadFileLinkIdx, //取文件的缓存编号。1字节
    ENbyWriteFileLinkIdx, //写文件的缓存编号。1字节
    /***************HUB 保存信息*********************/
    ENbyBestAntIdx, //最佳天线

    //只存ram
    ENbyHubUsartSeq,
    ENbyPanelUsartSeq,

    ENbyEvtA0TNS,  //自身事件串口发送次数
    ENbyEvtA1TNS,  //外设事件串口发送次数
    ENbyEvtA2TNS,  //文件传输事件串口发送次数

    ENbyEvtA0AckFlag, //自身事件等待应答标志
    ENbyEvtA1AckFlag, //外设事件等待应答标志
    ENbyEvtA2AckFlag, //文件传输事件等待应答标志

    ENbyBcastBusy,  //如广播繁忙，置1  1byte
    ENbyCfgReq,     //初始化置1 请求参数初始化，1byte

    ENbyFreq,       //频点 1byte
    ENbyjamming,    //检测的信号强度阈值 1byte
    ENbycustcode,   //顾客校验码 1byte

    ENbyLedCtrlFlag, //1：有新的LedCtrl物模型需要应答给RFM， 应答之后需置0
    ENbyOperateCtrlFlag,//1：有新的OperateCtrl物模型需要应答给RFM， 应答之后需置0
    ENbyKeyValueGetFlag,//1 ：有新的KeyValueGet物模型需要应答给RFM， 应答之后需置0
    ENbyOtaConSultFlag, //0xfe物模型是否填充到报文的flag 1字节, 应答之后需置0

    ENbyLedCtrl,      //LedCtrl物模型
    ENbyOperateCtrl,   //OperateCtrl物模型
    ENbyKeyValueGet,  //KeyValueGet物模型

    ENbyLocalRegister,  //panel do本地注册保存的进入\退出本地注册模式
    ENbyRegisterMAC,    //panel do MAC注册\扫码注册时保存的MAC信息
    ENbyRegisterQrKey,  //panel do扫码注册时保存的QR_KEY信息
    ENbyRegisterSN,     //panel do序列号注册时保存的序列号

    ENbyResetMode,  //panel 设置HUB reset
    ENbyEnableRetrans, //使能com口重传功能
    ENbyRealRssi,
    ENbyAvgRssi,

    ENbyPanelSetOtaMode, // OTA 前台升级/后台升级
    ENbyPanelSetOtaNum, //OTA ID[]数量
    ENbyPanelSetOtaId,  //OTA ID[]

    ENbyDelayTxTask,
    ENbyIOenLock,

    ENbyRssiLimit,
    ENbyNVMVersion,
    ENbytest, //test
    ENbyASeqLed,
    ENbyASeqOperate,

    /***************HUB 节点信息 ******************/
    ENbyNodeJoinInfo=0x8000,                      //节点注册信息(含数量) 256个节点信息,占用32Bytes //TODO:位置固定
    ENpbyCodeABNodeFirst,                         //节点1 CodeAB key，16bytes
    ENpbyCodeABNode1=ENpbyCodeABNodeFirst,
    /****/
    ENpbyCodeABNodeLast=ENpbyCodeABNodeFirst+NODE_MAX_COUNT-1,
    ENpbyLocalIDFirst,                            //节点1 LocalID区域 2bytes
    /****/
    ENpbyLocalIDLast=ENpbyLocalIDFirst+NODE_MAX_COUNT-1,
    ENpbyNodeSNFirst,                             //节点1 SN区域，16bytes
    /****/
    ENpbyNodeSNLast=ENpbyNodeSNFirst+NODE_MAX_COUNT-1,
    ENbyNodeMacAddrFirst,                         //节点MAC address，8bytes
    /****/
    ENbyNodeMacAddrLast=ENbyNodeMacAddrFirst+NODE_MAX_COUNT-1, //节点MAC address，8bytes

    HubRecvRollingCodeFirst,  //节点rolling code 字节长度 = NODE_MAX_COUNT*4
    /******/
    HubRecvRollingCodeLast = HubRecvRollingCodeFirst + NODE_MAX_COUNT-1,

    ENpbyNodeQrfH1First,      //节点1 QrfH1 1byte
    /****/
    ENpbyNodeQrfH1Last=ENpbyNodeQrfH1First+NODE_MAX_COUNT-1,

    ENpbyNodeQrfH2First,      //节点1 QrfH2 1byte
    /****/
    ENpbyNodeQrfH2Last=ENpbyNodeQrfH2First+NODE_MAX_COUNT-1,

    ENpbyNodeQrfR1First,      //节点1 QrfR1 1byte
    /****/
    ENpbyNodeQrfR1Last=ENpbyNodeQrfR1First+NODE_MAX_COUNT-1,

    ENpbyNodeQrfR2First,      //节点1 QrfR2 1byte
    /****/
    ENpbyNodeQrfR2Last=ENpbyNodeQrfR2First+NODE_MAX_COUNT-1,

    ENpbyNodeGroupIdxFirst,      //节点1 GroupIdx 1byte
    /****/
    ENpbyNodeGroupIdxLast=ENpbyNodeGroupIdxFirst+NODE_MAX_COUNT-1,

    ENpbyNodeOptionFirst,      //节点1 option 3bytes
    /****/
    ENpbyNodeOptionLast=ENpbyNodeOptionFirst+NODE_MAX_COUNT-1,

    ENpbyNodeDeviceTypeFirst,      //节点1 devicetype modeltype hardtype 3byte
    /****/
    ENpbyNodeDeviceTypeLast=ENpbyNodeDeviceTypeFirst+NODE_MAX_COUNT-1,


    ENbyNodeDeviceOptionFirst,     //节点1 option 1byte
    /***/
    ENbyNodeDeviceOptionLast=ENbyNodeDeviceOptionFirst+NODE_MAX_COUNT-1,

    ENbylastKeyIndex,


}DEVICE_ATTRIBUTE_EN;

typedef enum {
  HUB_API_LOG,
  FILE_API_LOG,
  MAC_API_LOG,
  NET_API_LOG,

}API_LOG_E;

void setDeviceSpvnTime(SPVN_TIME_EN spvnT);
SPVN_TIME_EN getDeviceSpvnTime();
//获取该设备的频段
RF_FREQ_EN getDeviceRfFreq(void);
//设置改设备的频段,设置后需重启设备，以重新初始化RF和FHSS序列
void setDeviceRfFreq(RF_FREQ_EN freq);
void printfDeviceRfFreqInfo();
/***
 *@brief 设置自身的属性参数，参数可存在RAM或FLASH中
 *@param DEVICE_ATTRIBUTE_EN attr属性
 *@param void*pData [in]入参，参数内容
 *@return int >=0  sucess； -1 failed
 * 
*/
int setThisParam(DEVICE_ATTRIBUTE_EN attr, void* pData);

/***
 *@brief 获取自身的属性参数，参数可存在RAM或FLASH中
 *@param DEVICE_ATTRIBUTE_EN attr属性
 *@param void*pData [out] 出参，返回参数内容
 *@return int >=0  sucess； -1 failed
 * 
*/
int getThisParam(DEVICE_ATTRIBUTE_EN attr, void* pData);


/***
 *@brief 仅HUB使用，获取下辖已连接的RFM的属性参数，参数可存在RAM或FLASH中
 *@param DEVICE_ATTRIBUTE_EN attr属性
 *@param void*pData [in] 出参，返回参数内容
 *@return int >=0  sucess； -1 failed
 * 
*/
int setDeviceParam(uint8_t nodeId ,DEVICE_ATTRIBUTE_EN attr, void* pData);

/***
 *@brief 仅HUB使用，获取下辖已连接的RFM的属性参数，参数可存在RAM或FLASH中
 *@param DEVICE_ATTRIBUTE_EN attr属性
 *@param void*pData [out] 出参，返回参数内容
 *@return int >=0  sucess； -1 failed
 * 
*/
int getDeviceParam(uint8_t nodeId ,DEVICE_ATTRIBUTE_EN attr, void* pData);

/***
 *@brief 仅HUB使用，通过分配的RFMId来设置MAC Address
 *@param mac:   8Bytes mac address
 *@param id:    RFMId 1byte,注册时分配
 *@param
 *
*/
void setNodeJoinMac(uint8_t *mac,uint8_t id);
/***
 *@brief 仅HUB使用，通过RFMId获取MAC Address
 *@param id: RFMId 1byte
 *@param mac: 8Bytes mac address
 *
*/
void getNodeJoinMac (uint8_t *mac,uint8_t id);

/*
 *@brief 仅HUB使用，通过RFMID设置codeAB
 *@param id: RFMId 1byte
 *@param key: RFMId对应的codeAB
 */
void setNodeJoinCodeAB(uint8_t *key,uint8_t id);

/*
 *@brief 仅HUB使用，通过RFMID读取codeAB
 *@param id: RFMId 1byte
 *@param key: RFMId对应的codeAB
 */
void getNodeJoinCodeAB(uint8_t *key,uint8_t id);
/*
 *@brief 获取mac 低4个字节
 */
uint32_t getMacAdd4(void);
#if defined (HUB_DEVICE)
void set_node_join_info_src_nvm(void);
/*
 * @brief 获取已注册的RFM的MAC
 */
void getAllNodeJoinMac (void);
void printAllNodeJoinMac (void);
void printOneNodeJoinMac(uint8_t id);
/*
 * @brief 判断是否是已注册的mac地址
 * @param mac 待比较的mac
 * @return true 是已注册的mac;false 不是已注册的mac
 */
bool isJoinMac(uint8_t *mac);
#endif
/*
 *@brief nvm初始化以及device参数初始化
 */
void nvm_device_init (void);
bool memcmp_sn(unsigned char *sn);

int api_log_enable_init(void);
int set_api_log_enable(API_LOG_E api_module, bool onoff);
int get_api_log_enable(API_LOG_E api_module, bool *ptr_onoff);
int set_api_log_enable_multiple_module(unsigned char *byte1,
                                       unsigned char *byte2,
                                       unsigned char *byte3,
                                       unsigned char *byte4);

void clean_device_ram_qrfh(unsigned char rfmid);
void clean_device_ram_qrfh_and_option(unsigned char rfmid);

void set_qrfh_countdown(unsigned char rfmid, unsigned char countdown);
unsigned char get_qrfh_countdown(unsigned char rfmid);
void update_rfm_qrfh_countdown(unsigned char rfmid);

void lock_rfm_join_pub(unsigned char rfmid);
bool check_rfm_is_join_pub_lock(unsigned char rfmid);
#endif
